//
// Created by xsh on 2025/5/27.
//
// 示例合成器

#ifndef OSC3_H
#define OSC3_H

#include <jni.h>
#include "../../../../common/include/LogUtil.h"
#include "../../../../common/include/Instrument.h"
const char* tag = "SubSynth";

class LFO{
public:
    enum WaveType {SINE,SAWTOOTH,TRIANGLE};
    //这一行代码是 C++ 中类的构造函数的初始化列表语法，用于初始化类的成员变量。
    LFO() : frequency(0.0), amplitude(0.0), currentPhase(0.0), waveType(WaveType::SINE) {}

public:
    double frequency;
    double amplitude;
    double currentPhase;
    WaveType waveType;

    double generateSample(double sampleRate) {
        double phaseIncrement = 2.0 * M_PI * frequency / sampleRate;
        double waveValue = 0.0;

        switch (waveType) {
            case WaveType::SINE:
                waveValue = sin(currentPhase);
                break;
            case WaveType::SAWTOOTH:
                waveValue = 2.0 * (fmod(currentPhase, 2 * M_PI) / (2 * M_PI)) - 1.0;
                break;
            case WaveType::TRIANGLE:
                waveValue = (currentPhase < M_PI) ? (currentPhase / M_PI) * 2.0 - 1.0 : ((currentPhase - M_PI) / M_PI) * -2.0 + 1.0;
                break;
        }

        currentPhase += phaseIncrement;
        if (currentPhase >= 2 * M_PI) currentPhase -= 2 * M_PI;
        //LOGD(tag,"LfoSample:%f",waveValue);
        return amplitude * waveValue;
    }

public:
    void setAmp(double amp)
    {
        this->amplitude = amp;
        LOGD(tag,"in LFO Class call:lfoampset:%f",amp);
    }
    void setFrequency(double freq)
    {
        this->frequency = freq;
        LOGD(tag,"in LFO Class call:lfofreq:%f",freq);
    }
    void setWaveType(WaveType type)
    {
        this->waveType = type;
        LOGD(tag,"lfoWaveType:%d",type);
    }
};
class SubSynth: public Instrument{
public:
    LFO lfo;
public:
    enum WaveType { SINE, SAWTOOTH, TRAN};//SQUARE 方波生成会崩溃
    enum FilterType{LP,HP};
    FilterType currentFilter;
    bool apply_Filter = false;
    bool apply_lfo = false;
    enum volEnv {A,D,S,R};
    enum LfoType {VOL,PHASE,PITCH};
    LfoType current_lfo_type;
    double amp = 1;
    //double frequency = 261.63; //默认c4 440.0
    // 参考Fl studio实现是float time 0-1
    struct ADSR{
        double attackTime; //秒 // 原float
        double decayTime;
        double sustainLevel;
        double releaseTime; // 0-1
        double currentTime;
        bool isReleased;
        enum Stage{ATTACK,DECAY,SUSTATIN,RELEASE,IDLE} stage;
        bool isNoteOn;
    };
    // 秒单位
    struct ADSRMaxTime {
        int maxAttack;
        int maxDecay;
        int maxRelease;
    };
    bool useVolEnv = false;
    ADSR adsr{};
    ADSRMaxTime adsrMaxTime{};
    float volEnvValue{};
    struct Oscillator{
        double frequency;
        double amp;
        WaveType waveform;
        double currentPhase;
        void generate(short* buffer, int numSamples, double sampleRate);
    };

public:
    void changeWave(WaveType type);
    // 删除或者重构
    void changeNote(int note);
    void noteOn();  //adsr
    void noteOff();
    // 需要重构
    void changeVolEnv(volEnv type,double value);
    //double genWithLfo(short* buffer, int numSamples, double sampleRate);
    double genWave(short* buffer, int numSamples,double phase, double sampleRate) override ;
    void onEvent(const char *eventName, jdouble value) override ;
    void onEvent(const char *eventName, jint value) override ;
    void onEvent(const char *eventName, bool value) override ;
    void printADSRState();
    Oscillator osc1;
    Oscillator osc2;

    SubSynth();
    void setWaveForm(int index,WaveType type);

};

extern "C" SubSynth* createInstrument();
#endif

